home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / QuickTime / QuickTime 3 Interfaces & Libs / QTDevWin / CIncludes / PEFBinaryFormat.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-21  |  50.5 KB  |  1,141 lines  |  [TEXT/dosa]

  1. /*
  2.      File:        PEFBinaryFormat.h
  3.  
  4.      Contains:    PEF Types and Macros
  5.  
  6.      Version:    Technology:    Master Interfaces
  7.                  Release:    QuickTime 3.0
  8.  
  9.      Copyright:    © 1993-1998, 1998 by Apple Computer, Inc., all rights reserved.
  10.  
  11.      Bugs?:        Please include the the file and version information (from above) with
  12.                  the problem description.  Developers belonging to one of the Apple
  13.                  developer programs can submit bug reports to:
  14.  
  15.                      devsupport@apple.com
  16.  
  17. */
  18.  
  19.  
  20. #ifndef __PEFBINARYFORMAT__
  21. #define __PEFBINARYFORMAT__
  22.  
  23. #ifndef __MACTYPES__
  24. #include <MacTypes.h>
  25. #endif
  26.  
  27.  
  28.  
  29. #if PRAGMA_ONCE
  30. #pragma once
  31. #endif
  32.  
  33. #ifdef __cplusplus
  34. extern "C" {
  35. #endif
  36.  
  37. #if PRAGMA_IMPORT
  38. #pragma import on
  39. #endif
  40.  
  41. #if PRAGMA_STRUCT_ALIGN
  42.     #pragma options align=mac68k
  43. #elif PRAGMA_STRUCT_PACKPUSH
  44.     #pragma pack(push, 2)
  45. #elif PRAGMA_STRUCT_PACK
  46.     #pragma pack(2)
  47. #endif
  48.  
  49.  
  50.  
  51. /* -----------------------------------------------------------------------------------------    */
  52. /* Almost all types are padded for natural alignment.  However the PEFExportedSymbol type is    */
  53. /* 10 bytes long, containing two 32 bit fields and one 16 bit field.  Arrays of it must be        */
  54. /* packed, so it requires "68K" alignment.  Setting this globally to 68K should also help        */
  55. /* ensure consistent treatment across compilers.                                                */
  56.  
  57.  
  58.  
  59. /* ======================================================================================== */
  60. /* Overall Structure */
  61. /* ================= */
  62.  
  63.  
  64.  
  65. /* -------------------------------------------------------------------------------------------    */
  66. /* This header contains a complete set of types and macros for dealing with the PEF executable    */
  67. /* format.  While some description is provided, this header is not meant as a primary source    */
  68. /* of documentation on PEF.  An excellent specification of PEF can be found in the Macintosh    */
  69. /* Runtime Architectures book.  This header is primarily a physical format description.  Thus    */
  70. /* it depends on as few other headers as possible and structure fields have obvious sizes.        */
  71. /*                                                                                                 */
  72. /* The physical storage for a PEF executable is known as a "container".  This refers to just    */
  73. /* the executable itself, not the file etc.  E.g. if five DLLs are packaged in a single file's    */
  74. /* data fork, that one data fork has five containers within it.                                    */
  75. /*                                                                                                 */
  76. /* A PEF container consists of an overall header, followed by one or more section headers,        */
  77. /* followed by the section name table, followed by the contents for the sections.  Some kinds    */
  78. /* of sections have specific internal representation.  The "loader" section is the most common    */
  79. /* of these special sections.  It contains information on the exports, imports, and runtime        */
  80. /* relocations required to prepare the executable.  PEF containers are self contained, all        */
  81. /* portions are located via relative offsets.                                                    */
  82. /*                                                                                                 */
  83. /*                                                                                                 */
  84. /*            +-------------------------------+                                                    */
  85. /*            |        Container Header        |    40 bytes                                        */
  86. /*            +-------------------------------+                                                    */
  87. /*            |        Section 0 header        |    28 bytes each                                    */
  88. /*            |...............................|                                                    */
  89. /*            |            - - - -                |                                                    */
  90. /*            |...............................|                                                    */
  91. /*            |        Section n-1 header        |                                                    */
  92. /*            +-------------------------------+                                                    */
  93. /*            |        Section Name Table        |                                                    */
  94. /*            +-------------------------------+                                                    */
  95. /*            |        Section x raw data        |                                                    */
  96. /*            +-------------------------------+                                                    */
  97. /*             |            - - - -                |                                                    */
  98. /*            +-------------------------------+                                                    */
  99. /*            |        Section y raw data        |                                                    */
  100. /*            +-------------------------------+                                                    */
  101. /*                                                                                                 */
  102. /*                                                                                                 */
  103. /* The sections are implicitly numbered from 0 to n according to the order of their headers.    */
  104. /* The headers of the instantiated sections must precede those of the non-instantiated            */
  105. /* sections.  The ordering of the raw data is independent of the section header ordering.        */
  106. /* Each section header contains the offset for that section's raw data.                            */
  107.  
  108.  
  109.  
  110. /* =========================================================================================== */
  111. /* Container Header */
  112. /* ================ */
  113.  
  114.  
  115.  
  116.  
  117. struct PEFContainerHeader {
  118.     OSType                             tag1;                        /* Must contain 'Joy!'. */
  119.     OSType                             tag2;                        /* Must contain 'peff'.  (Yes, with two 'f's.) */
  120.     OSType                             architecture;                /* The ISA for code sections.  Constants in CodeFragments.h. */
  121.     UInt32                             formatVersion;                /* The physical format version. */
  122.     UInt32                             dateTimeStamp;                /* Macintosh format creation/modification stamp. */
  123.     UInt32                             oldDefVersion;                /* Old definition version number for the code fragment. */
  124.     UInt32                             oldImpVersion;                /* Old implementation version number for the code fragment. */
  125.     UInt32                             currentVersion;                /* Current version number for the code fragment. */
  126.     UInt16                             sectionCount;                /* Total number of section headers that follow. */
  127.     UInt16                             instSectionCount;            /* Number of instantiated sections. */
  128.     UInt32                             reservedA;                    /* Reserved, must be written as zero. */
  129. };
  130. typedef struct PEFContainerHeader        PEFContainerHeader;
  131.  
  132. enum {
  133.     kPEFTag1                    = FOUR_CHAR_CODE('Joy!'),        /* For non-Apple compilers: 0x4A6F7921. */
  134.     kPEFTag2                    = FOUR_CHAR_CODE('peff'),        /* For non-Apple compilers: 0x70656666. */
  135.     kPEFVersion                    = 0x00000001
  136. };
  137.  
  138.  
  139.  
  140. enum {
  141.     kPEFFirstSectionHeaderOffset = sizeof(PEFContainerHeader)
  142. };
  143.  
  144. #define PEFFirstSectionNameOffset(container)    \
  145.             ( kPEFFirstSectionHeaderOffset + ((container)->sectionCount * sizeof ( PEFSectionHeader )) )
  146.  
  147.  
  148.  
  149. /* =========================================================================================== */
  150. /* Section Headers */
  151. /* =============== */
  152.  
  153.  
  154.  
  155.  
  156. struct PEFSectionHeader {
  157.     SInt32                             nameOffset;                    /* Offset of name within the section name table, -1 => none. */
  158.     UInt32                             defaultAddress;                /* Default address, affects relocations. */
  159.     UInt32                             totalLength;                /* Fully expanded size in bytes of the section contents. */
  160.     UInt32                             unpackedLength;                /* Size in bytes of the "initialized" part of the contents. */
  161.     UInt32                             containerLength;            /* Size in bytes of the raw data in the container. */
  162.     UInt32                             containerOffset;            /* Offset of section's raw data. */
  163.     UInt8                             sectionKind;                /* Kind of section contents/usage. */
  164.     UInt8                             shareKind;                    /* Sharing level, if a writeable section. */
  165.     UInt8                             alignment;                    /* Preferred alignment, expressed as log 2. */
  166.     UInt8                             reservedA;                    /* Reserved, must be zero. */
  167. };
  168. typedef struct PEFSectionHeader            PEFSectionHeader;
  169.  
  170. enum {
  171.                                                                 /* Values for the sectionKind field. */
  172.                                                                 /*    Section kind values for instantiated sections. */
  173.     kPEFCodeSection                = 0,                            /* Code, presumed pure & position independent. */
  174.     kPEFUnpackedDataSection        = 1,                            /* Unpacked writeable data. */
  175.     kPEFPackedDataSection        = 2,                            /* Packed writeable data. */
  176.     kPEFConstantSection            = 3,                            /* Read-only data. */
  177.     kPEFExecDataSection            = 6,                            /* Intermixed code and writeable data. */
  178.                                                                 /* Section kind values for non-instantiated sections. */
  179.     kPEFLoaderSection            = 4,                            /* Loader tables. */
  180.     kPEFDebugSection            = 5,                            /* Reserved for future use. */
  181.     kPEFExceptionSection        = 7,                            /* Reserved for future use. */
  182.     kPEFTracebackSection        = 8                                /* Reserved for future use. */
  183. };
  184.  
  185.  
  186.  
  187. enum {
  188.                                                                 /* Values for the shareKind field. */
  189.     kPEFProcessShare            = 1,                            /* Shared within a single process. */
  190.     kPEFGlobalShare                = 4,                            /* Shared across the entire system. */
  191.     kPEFProtectedShare            = 5                                /* Readable across the entire system, writeable only to privileged code. */
  192. };
  193.  
  194.  
  195.  
  196.  
  197. /* =========================================================================================== */
  198. /* Packed Data Contents */
  199. /* ==================== */
  200.  
  201.  
  202.  
  203. /* -------------------------------------------------------------------------------------------    */
  204. /* The raw contents of a packed data section are a sequence of byte codes.  The basic format    */
  205. /* has a 3 bit opcode followed by a 5 bit count.  Additional bytes might be used to contain        */
  206. /* counts larger than 31, and to contain a second or third count.  Further additional bytes        */
  207. /* contain actual data values to transfer.                                                        */
  208. /*                                                                                                 */
  209. /* All counts are represented in a variable length manner.  A zero in the initial 5 bit count    */
  210. /* indicates the actual value follows.  In this case, and for the second and third counts, the    */
  211. /* count is represented as a variable length sequence of bytes.  The bytes are stored in big    */
  212. /* endian manner, most significant part first.  The high order bit is set in all but the last    */
  213. /* byte.  The value is accumulated by shifting the current value up 7 bits and adding in the    */
  214. /* low order 7 bits of the next byte.                                                            */
  215.  
  216.  
  217.  
  218. enum {
  219.                                                                 /* The packed data opcodes. */
  220.     kPEFPkDataZero                = 0,                            /* Zero fill "count" bytes. */
  221.     kPEFPkDataBlock                = 1,                            /* Block copy "count" bytes. */
  222.     kPEFPkDataRepeat            = 2,                            /* Repeat "count" bytes "count2"+1 times. */
  223.     kPEFPkDataRepeatBlock        = 3,                            /* Interleaved repeated and unique data. */
  224.     kPEFPkDataRepeatZero        = 4                                /* Interleaved zero and unique data. */
  225. };
  226.  
  227.  
  228.  
  229. enum {
  230.     kPEFPkDataOpcodeShift        = 5,
  231.     kPEFPkDataCount5Mask        = 0x1F,
  232.     kPEFPkDataMaxCount5            = 31,
  233.     kPEFPkDataVCountShift        = 7,
  234.     kPEFPkDataVCountMask        = 0x7F,
  235.     kPEFPkDataVCountEndMask        = 0x80
  236. };
  237.  
  238.  
  239. #define PEFPkDataOpcode(byte) ( ((UInt8)(byte)) >> kPEFPkDataOpcodeShift )
  240.  
  241. #define PEFPkDataCount5(byte) ( ((UInt8)(byte)) & kPEFPkDataCount5Mask )
  242.  
  243. #define PEFPkDataComposeInstr(opcode,count5)        \
  244.             ( (((UInt8)(opcode)) << kPEFPkDataOpcodeShift) | ((UInt8)(count5)) )
  245.  
  246.  
  247.  
  248. /* ------------------------------------------------------------------------------------------    */
  249. /* The following code snippet can be used to input a variable length count.                        */
  250. /*                                                                                                 */
  251. /*        count = 0;                                                                                */
  252. /*        do {                                                                                    */
  253. /*            byte = *bytePtr++;                                                                    */
  254. /*            count = (count << kPEFPkDataVCountShift) | (byte & kPEFPkDataVCountMask);            */
  255. /*        } while ( (byte & kPEFPkDataVCountEndMask) != 0 );                                        */
  256. /*                                                                                                 */
  257. /* The following code snippet can be used to output a variable length count to a byte array.    */
  258. /* This is more complex than the input code because the chunks are output in big endian order.    */
  259. /* Think about handling values like 0 or 0x030000.                                                */
  260. /*                                                                                                 */
  261. /*        count = 1;.                                                                                */
  262. /*        tempValue = value >> kPEFPkDataCountShift;                                                */
  263. /*        while ( tempValue != 0 ) {                                                                */
  264. /*            count += 1;                                                                            */
  265. /*            tempValue = tempValue >> kPEFPkDataCountShift;                                        */
  266. /*        }                                                                                        */
  267. /*                                                                                                 */
  268. /*        bytePtr += count;                                                                        */
  269. /*        tempPtr = bytePtr - 1;                                                                    */
  270. /*        *tempPtr-- = value;        // ! No need to mask, only the low order byte is stored.        */
  271. /*        for ( count -= 1; count != 0; count -= 1 ) {                                            */
  272. /*            value = value >> kPEFPkDataCountShift;                                                */
  273. /*            *tempPtr-- = value | kPEFPkDataCountEndMask;                                        */
  274. /*        }                                                                                        */
  275.  
  276.  
  277.  
  278. /* =========================================================================================== */
  279. /* Loader Section */
  280. /* ============== */
  281.  
  282.  
  283.  
  284. /* ------------------------------------------------------------------------------------------    */
  285. /* The loader section contains information needed to prepare the code fragment for execution.    */
  286. /* This includes this fragment's exports, the import libraries and the imported symbols from    */
  287. /* each library, and the relocations for the writeable sections.                                */
  288. /*                                                                                                 */
  289. /*            +-----------------------------------+                <-- containerOffset --------+    */
  290. /*            |        Loader Info Header            |    56 bytes                                |    */
  291. /*            |-----------------------------------|                                            |    */
  292. /*            |        Imported Library 0            |    24 bytes each                            |    */
  293. /*            |...................................|                                            |    */
  294. /*            |            - - -                    |                                            |    */
  295. /*            |...................................|                                            |    */
  296. /*            |        Imported Library l-1        |                                            |    */
  297. /*            |-----------------------------------|                                            |    */
  298. /*            |        Imported Symbol 0            |    4 bytes each                            |    */
  299. /*            |...................................|                                            |    */
  300. /*            |            - - -                    |                                            |    */
  301. /*            |...................................|                                            |    */
  302. /*            |         Imported Symbol i-1            |                                            |    */
  303. /*            |-----------------------------------|                                            |    */
  304. /*            |        Relocation Header 0            |    12 bytes each                            |    */
  305. /*            |...................................|                                            |    */
  306. /*            |            - - -                    |                                            |    */
  307. /*            |...................................|                                            |    */
  308. /*            |        Relocation Header r-1        |                                            |    */
  309. /*            |-----------------------------------|                <-- + relocInstrOffset -----|    */
  310. /*            |        Relocation Instructions        |                                            |    */
  311. /*            |-----------------------------------|                <-- + loaderStringsOffset --|    */
  312. /*            |        Loader String Table            |                                            |    */
  313. /*            |-----------------------------------|                <-- + exportHashOffset -----+    */
  314. /*            |        Export Hash Slot 0            |    4 bytes each                                */
  315. /*            |...................................|                                                */
  316. /*            |            - - -                    |                                                */
  317. /*            |...................................|                                                */
  318. /*            |         Export Hash Slot h-1        |                                                */
  319. /*            |-----------------------------------|                                                */
  320. /*            |        Export Symbol Key 0            |    4 bytes each                                */
  321. /*            |...................................|                                                */
  322. /*            |            - - -                    |                                                */
  323. /*            |...................................|                                                */
  324. /*            |        Export Symbol Key e-1        |                                                */
  325. /*            |-----------------------------------|                                                */
  326. /*            |        Export Symbol 0                |    10 bytes each                                */
  327. /*            |...................................|                                                */
  328. /*            |            - - -                    |                                                */
  329. /*            |...................................|                                                */
  330. /*            |        Export Symbol e-1            |                                                */
  331. /*            +-----------------------------------+                                                */
  332.  
  333.  
  334.  
  335.  
  336. struct PEFLoaderInfoHeader {
  337.     SInt32                             mainSection;                /* Section containing the main symbol, -1 => none. */
  338.     UInt32                             mainOffset;                    /* Offset of main symbol. */
  339.     SInt32                             initSection;                /* Section containing the init routine's TVector, -1 => none. */
  340.     UInt32                             initOffset;                    /* Offset of the init routine's TVector. */
  341.     SInt32                             termSection;                /* Section containing the term routine's TVector, -1 => none. */
  342.     UInt32                             termOffset;                    /* Offset of the term routine's TVector. */
  343.     UInt32                             importedLibraryCount;        /* Number of imported libraries.  ('l') */
  344.     UInt32                             totalImportedSymbolCount;    /* Total number of imported symbols.  ('i') */
  345.     UInt32                             relocSectionCount;            /* Number of sections with relocations.  ('r') */
  346.     UInt32                             relocInstrOffset;            /* Offset of the relocation instructions. */
  347.     UInt32                             loaderStringsOffset;        /* Offset of the loader string table. */
  348.     UInt32                             exportHashOffset;            /* Offset of the export hash table. */
  349.     UInt32                             exportHashTablePower;        /* Export hash table size as log 2.  (Log2('h')) */
  350.     UInt32                             exportedSymbolCount;        /* Number of exported symbols.  ('e') */
  351. };
  352. typedef struct PEFLoaderInfoHeader        PEFLoaderInfoHeader;
  353.  
  354.  
  355. /* =========================================================================================== */
  356. /* Imported Libraries */
  357. /* ------------------ */
  358.  
  359.  
  360.  
  361. struct PEFImportedLibrary {
  362.     UInt32                             nameOffset;                    /* Loader string table offset of library's name. */
  363.     UInt32                             oldImpVersion;                /* Oldest compatible implementation version. */
  364.     UInt32                             currentVersion;                /* Current version at build time. */
  365.     UInt32                             importedSymbolCount;        /* Imported symbol count for this library. */
  366.     UInt32                             firstImportedSymbol;        /* Index of first imported symbol from this library. */
  367.     UInt8                             options;                    /* Option bits for this library. */
  368.     UInt8                             reservedA;                    /* Reserved, must be zero. */
  369.     UInt16                             reservedB;                    /* Reserved, must be zero. */
  370. };
  371. typedef struct PEFImportedLibrary        PEFImportedLibrary;
  372.  
  373. enum {
  374.                                                                 /* Bits for the PEFImportedLibrary options field. */
  375.     kPEFWeakImportLibMask        = 0x40,                            /* The imported library is allowed to be missing. */
  376.     kPEFInitLibBeforeMask        = 0x80                            /* The imported library must be initialized first. */
  377. };
  378.  
  379.  
  380.  
  381.  
  382. /* =========================================================================================== */
  383. /* Imported Symbols */
  384. /* ---------------- */
  385.  
  386.  
  387.  
  388. /* -------------------------------------------------------------------------------------------    */
  389. /* The PEFImportedSymbol type has the following bit field layout.                                */
  390. /*                                                                                                 */
  391. /*                                                                       3                        */
  392. /*         0             7 8                                             1                        */
  393. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  394. /*      | symbol class  | offset of symbol name in loader string table  |                        */
  395. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  396. /*        |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        */
  397.  
  398.  
  399.  
  400.  
  401. struct PEFImportedSymbol {
  402.     UInt32                             classAndName;
  403. };
  404. typedef struct PEFImportedSymbol        PEFImportedSymbol;
  405.  
  406. enum {
  407.     kPEFImpSymClassShift        = 24,
  408.     kPEFImpSymNameOffsetMask    = 0x00FFFFFF,
  409.     kPEFImpSymMaxNameOffset        = 0x00FFFFFF                    /* 16,777,215 */
  410. };
  411.  
  412. #define PEFImportedSymbolClass(classAndName)        ((UInt8) ((classAndName) >> kPEFImpSymClassShift))
  413. #define PEFImportedSymbolNameOffset(classAndName)    ((classAndName) & kPEFImpSymNameOffsetMask)
  414.  
  415. #define PEFComposeImportedSymbol(class,nameOffset)        \
  416.             ( ( ((UInt32)(class)) << kPEFImpSymClassShift ) | ( (UInt32)(nameOffset) ) )
  417.  
  418.  
  419. enum {
  420.                                                                 /* Imported and exported symbol classes. */
  421.     kPEFCodeSymbol                = 0x00,
  422.     kPEFDataSymbol                = 0x01,
  423.     kPEFTVectorSymbol            = 0x02,
  424.     kPEFTOCSymbol                = 0x03,
  425.     kPEFGlueSymbol                = 0x04,
  426.     kPEFUndefinedSymbol            = 0x0F,
  427.     kPEFWeakImportSymMask        = 0x80
  428. };
  429.  
  430.  
  431.  
  432.  
  433. /* =========================================================================================== */
  434. /* Exported Symbol Hash Table */
  435. /* -------------------------- */
  436.  
  437.  
  438.  
  439. /* -------------------------------------------------------------------------------------------    */
  440. /* Exported symbols are described in four parts, optimized for speed of lookup.  These parts    */
  441. /* are the "export hash table", the "export key table", the "export symbol table", and the        */
  442. /* "export name table".  Overall they contain a flattened representation of a fairly normal        */
  443. /* hashed symbol table.                                                                            */
  444. /*                                                                                                */
  445. /* The export hash table is an array of small fixed size elements.  The number of elements is    */
  446. /* a power of 2.  A 32 bit hash word for a symbol is converted into an index into this array.    */
  447. /* Each hash slot contains a count of the number of exported symbols that map to this slot and    */
  448. /* the index of the first of those symbols in the key and symbol tables.  Of course some hash    */
  449. /* slots will have a zero count.                                                                */
  450. /*                                                                                                */
  451. /* The key and symbol tables are also arrays of fixed size elements, one for each exported        */
  452. /* symbol.  Their entries are grouped by hash slot, those elements mapping to the same hash        */
  453. /* slot are contiguous.  The key table contains just the full 32 bit hash word for each            */
  454. /* exported symbol.  The symbol table contains the offset of the symbol's name in the string    */
  455. /* table and other information about the exported symbol.                                        */
  456. /*                                                                                                */
  457. /* To look up an export you take the hashword and compute the hash slot index.  You then scan    */
  458. /* the indicated portion of the key table for matching hashwords.  If a hashword matches, you    */
  459. /* look at the corresponding symbol table entry to find the full symbol name.  If the names        */
  460. /* match the symbol is found.                                                                    */
  461.  
  462.  
  463.  
  464. /* -------------------------------------------------------------------------------------------    */
  465. /* The following function may be used to compute the hash table size.  Signed values are used    */
  466. /* just to avoid potential code generation overhead for unsigned division.                        */
  467. /*                                                                                                 */
  468. /*        UInt8    PEFComputeHashTableExponent    ( SInt32    exportCount )                            */
  469. /*        {                                                                                        */
  470. /*            SInt32    exponent;                                                                    */
  471. /*                                                                                                 */
  472. /*            const SInt32    kExponentLimit        = 16;    // Arbitrary, but must not exceed 30.    */
  473. /*            const SInt32    kAverageChainLimit    = 10;    // Arbitrary, for space/time tradeoff.    */
  474. /*                                                                                                 */
  475. /*            for ( exponent = 0; exponent < kExponentLimit; exponent += 1 ) {                    */
  476. /*                if ( (exportCount / (1 << exponent)) < kAverageChainLimit ) break;                */
  477. /*            }                                                                                    */
  478. /*                                                                                                 */
  479. /*            return exponent;                                                                    */
  480. /*                                                                                                 */
  481. /*        }    // PEFComputeHashTableExponent ()                                                    */
  482.  
  483.  
  484.  
  485. /* -------------------------------------------------------------------------------------------    */
  486. /* The PEFExportedSymbolHashSlot type has the following bit field layout.                        */
  487. /*                                                                                                 */
  488. /*                                   1 1                                 3                        */
  489. /*         0                         3 4                                 1                        */
  490. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  491. /*        | symbol count              | index of first export key         |                        */
  492. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  493. /*        |<-- 14 bits -------------->|<-- 18 bits ---------------------->|                        */
  494.  
  495.  
  496.  
  497.  
  498. struct PEFExportedSymbolHashSlot {
  499.     UInt32                             countAndStart;
  500. };
  501. typedef struct PEFExportedSymbolHashSlot PEFExportedSymbolHashSlot;
  502.  
  503. enum {
  504.     kPEFHashSlotSymCountShift    = 18,
  505.     kPEFHashSlotFirstKeyMask    = 0x0003FFFF,
  506.     kPEFHashSlotMaxSymbolCount    = 0x00003FFF,                    /*  16,383 */
  507.     kPEFHashSlotMaxKeyIndex        = 0x0003FFFF                    /* 262,143 */
  508. };
  509.  
  510. #define PEFHashTableIndex(fullHashWord,hashTablePower)    \
  511.             ( ( (fullHashWord) ^ ((fullHashWord) >> (hashTablePower)) ) & ((1 << (hashTablePower)) - 1) )
  512.  
  513. #define PEFHashSlotSymbolCount(countAndStart)    ((UInt32) ((countAndStart) >> kPEFHashSlotSymCountShift))
  514. #define PEFHashSlotFirstKey(countAndStart)        ((countAndStart) & kPEFHashSlotFirstKeyMask)
  515.  
  516. #define PEFComposeExportedSymbolHashSlot(symbolCount,firstKey)    \
  517.             ( ( ((UInt32)(symbolCount)) << kPEFHashSlotSymCountShift ) | ( (UInt32)(firstKey) ) )
  518.  
  519.  
  520.  
  521. /* =========================================================================================== */
  522. /* Exported Symbol Hash Key */
  523. /* ------------------------ */
  524.  
  525.  
  526.  
  527.  
  528. struct PEFSplitHashWord {
  529.     UInt16                             nameLength;
  530.     UInt16                             hashValue;
  531. };
  532. typedef struct PEFSplitHashWord            PEFSplitHashWord;
  533.  
  534. struct PEFExportedSymbolKey {
  535.     union {
  536.         UInt32                             fullHashWord;
  537.         PEFSplitHashWord                 splitHashWord;
  538.     }                                 u;
  539. };
  540. typedef struct PEFExportedSymbolKey        PEFExportedSymbolKey;
  541.  
  542. enum {
  543.     kPEFHashLengthShift            = 16,
  544.     kPEFHashValueMask            = 0x0000FFFF,
  545.     kPEFHashMaxLength            = 0x0000FFFF                    /* 65,535 */
  546. };
  547.  
  548. #define PEFHashNameLength(fullHashWord)    ((UInt32) ((fullHashWord) >> kPEFHashLengthShift))
  549. #define PEFHashValue(fullHashWord)    ((fullHashWord) & kPEFHashValueMask)
  550.  
  551. #define PEFComposeFullHashWord(nameLength,hashValue)    \
  552.             ( ( ((UInt32)(nameLength)) << kPEFHashLengthShift ) | ( (UInt32)(hashValue) ) )
  553.  
  554.  
  555.  
  556. /* -------------------------------------------------------------------------------------------            */
  557. /* The following function computes the full 32 bit hash word.                                            */
  558. /*                                                                                                         */
  559. /*        UInt32    PEFComputeHashWord    ( BytePtr    nameText,        // ! First "letter", not length byte.    */
  560. /*                                      UInt32    nameLength )    // ! The text may be zero terminated.    */
  561. /*        {                                                                                                */
  562. /*            BytePtr    charPtr        = nameText;                                                                */
  563. /*            SInt32    hashValue    = 0;        // ! Signed to match old published algorithm.                */
  564. /*            UInt32    length        = 0;                                                                    */
  565. /*            UInt32    limit;                                                                                */
  566. /*            UInt32    result;                                                                                */
  567. /*            UInt8    currChar;                                                                            */
  568. /*                                                                                                         */
  569. /*            #define PseudoRotate(x)  ( ( (x) << 1 ) - ( (x) >> 16 ) )                                    */
  570. /*                                                                                                         */
  571. /*            for ( limit = nameLength; limit > 0; limit -= 1 ) {                                            */
  572. /*                currChar = *charPtr++;                                                                    */
  573. /*                if ( currChar == NULL ) break;                                                            */
  574. /*                length += 1;                                                                            */
  575. /*                hashValue = PseudoRotate ( hashValue ) ^ currChar;                                        */
  576. /*            }                                                                                            */
  577. /*                                                                                                         */
  578. /*            result    = (length << kPEFHashLengthShift) |                                                    */
  579. /*                      ((UInt16) ((hashValue ^ (hashValue >> 16)) & kPEFHashValueMask));                    */
  580. /*                                                                                                         */
  581. /*            return result;                                                                                */
  582. /*                                                                                                         */
  583. /*        }    // PEFComputeHashWord ()                                                                    */
  584.  
  585.  
  586.  
  587. /* =========================================================================================== */
  588. /* Exported Symbols */
  589. /* ---------------- */
  590.  
  591.  
  592.  
  593.  
  594. struct PEFExportedSymbol {                                        /* ! This structure is 10 bytes long and arrays are packed. */
  595.     UInt32                             classAndName;                /* A combination of class and name offset. */
  596.     UInt32                             symbolValue;                /* Typically the symbol's offset within a section. */
  597.     SInt16                             sectionIndex;                /* The index of the section, or pseudo-section, for the symbol. */
  598. };
  599. typedef struct PEFExportedSymbol        PEFExportedSymbol;
  600.  
  601. /* -------------------------------------------------------------------------------------------    */
  602. /* The classAndName field of the PEFExportedSymbol type has the following bit field layout.        */
  603. /*                                                                                                 */
  604. /*                                                                       3                        */
  605. /*         0             7 8                                             1                        */
  606. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  607. /*      | symbol class  | offset of symbol name in loader string table  |                        */
  608. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  609. /*        |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        */
  610.  
  611.  
  612.  
  613. enum {
  614.     kPEFExpSymClassShift        = 24,
  615.     kPEFExpSymNameOffsetMask    = 0x00FFFFFF,
  616.     kPEFExpSymMaxNameOffset        = 0x00FFFFFF                    /* 16,777,215 */
  617. };
  618.  
  619. #define PEFExportedSymbolClass(classAndName)        ((UInt8) ((classAndName) >> kPEFExpSymClassShift))
  620. #define PEFExportedSymbolNameOffset(classAndName)    ((classAndName) & kPEFExpSymNameOffsetMask)
  621.  
  622. #define PEFComposeExportedSymbol(class,nameOffset)        \
  623.             ( ( ((UInt32)(class)) << kPEFExpSymClassShift ) | ( (UInt32)(nameOffset) ) )
  624.  
  625.  
  626. enum {
  627.                                                                 /* Negative section indices indicate pseudo-sections. */
  628.     kPEFAbsoluteExport            = -2,                            /* The symbol value is an absolute address. */
  629.     kPEFReexportedImport        = -3                            /* The symbol value is the index of a reexported import. */
  630. };
  631.  
  632.  
  633.  
  634.  
  635. /* =========================================================================================== */
  636. /* Loader Relocations */
  637. /* ================== */
  638.  
  639.  
  640.  
  641. /* -------------------------------------------------------------------------------------------    */
  642. /* The relocations for a section are defined by a sequence of instructions for an abstract        */
  643. /* machine that is specifically geared to performing relocations commonly needed for the "CFM"    */
  644. /* code generation model.  These instructions occur in 16 bit chunks.  Most instructions have    */
  645. /* just a single chunk.  Instructions that are larger than 16 bits have an opcode and some of    */
  646. /* the operands in the first chunk, with other operands in following chunks.                    */
  647.  
  648.  
  649.  
  650.  
  651. typedef UInt16                             PEFRelocChunk;
  652.  
  653. struct PEFLoaderRelocationHeader {
  654.     UInt16                             sectionIndex;                /* Index of the section to be fixed up. */
  655.     UInt16                             reservedA;                    /* Reserved, must be zero. */
  656.     UInt32                             relocCount;                    /* Number of 16 bit relocation chunks. */
  657.     UInt32                             firstRelocOffset;            /* Offset of first relocation instruction. */
  658. };
  659. typedef struct PEFLoaderRelocationHeader PEFLoaderRelocationHeader;
  660.  
  661. /* -------------------------------------------------------------------------------------------    */
  662. /* ! Note that the relocCount field is the number of 16 bit relocation chunks, i.e. 1/2 the        */
  663. /* ! total number of bytes of relocation instructions.  While most relocation instructions are    */
  664. /* ! 16 bits long, some are longer so the number of complete relocation instructions may be        */
  665. /* ! less than the relocCount value.                                                            */
  666.  
  667.  
  668.  
  669. /* ----------------------------------------------------------------------------------    */
  670. /* The PEFRelocField macro is a utility for extracting relocation instruction fields.    */
  671.  
  672.  
  673. #define PEFRFShift(offset,length)    (16 - (offset + length))
  674. #define PEFRFMask(length)            ((1 << length) - 1)
  675.  
  676. #define PEFRelocField(chunk,offset,length)    \
  677.             ( ( (chunk) >> (16 - ((offset) + (length))) ) & ((1 << (length)) - 1) )
  678.  
  679.  
  680.  
  681. /* =========================================================================================== */
  682. /* Basic Relocation Opcodes */
  683. /* ------------------------ */
  684.  
  685.  
  686. /* ------------------------------------------------------------------------------------------    */
  687. /* The number of opcode bits varies from 2 to 7.  The enumeration and switch table given here    */
  688. /* are defined in terms of the most significant 7 bits of the first instruction chunk.  An        */
  689. /* instruction is decoded by using the most significant 7 bits as an index into the opcode        */
  690. /* table, which in turn contains appropriately masked forms of the most significant 7 bits.        */
  691. /* The macro PEFRelocBasicOpcode assumes a declaration of the form.                                */
  692. /*                                                                                                 */
  693. /*        UInt8 kPEFRelocBasicOpcodes [kPEFRelocBasicOpcodeRange] = { PEFMaskedBasicOpcodes };    */
  694.  
  695.  
  696.  
  697. enum {
  698.     kPEFRelocBasicOpcodeRange    = 128
  699. };
  700.  
  701. #define PEFRelocBasicOpcode(firstChunk) (kPEFRelocBasicOpcodes[(firstChunk)>>9])
  702.  
  703.  
  704.  
  705. /* -------------------------------------------------------------------------------------------    */
  706. /* The relocation opcodes, clustered by major and minor groups.  The instructions within a        */
  707. /* cluster all have the same bit field layout.  The enumeration values use the high order 7        */
  708. /* bits of the relocation instruction.  Unused low order bits are set to zero.                    */
  709.  
  710.  
  711. enum {
  712.     kPEFRelocBySectDWithSkip    = 0x00,                            /* Binary: 00x_xxxx */
  713.     kPEFRelocBySectC            = 0x20,                            /* Binary: 010_0000, group is "RelocRun" */
  714.     kPEFRelocBySectD            = 0x21,                            /* Binary: 010_0001 */
  715.     kPEFRelocTVector12            = 0x22,                            /* Binary: 010_0010 */
  716.     kPEFRelocTVector8            = 0x23,                            /* Binary: 010_0011 */
  717.     kPEFRelocVTable8            = 0x24,                            /* Binary: 010_0100 */
  718.     kPEFRelocImportRun            = 0x25,                            /* Binary: 010_0101 */
  719.     kPEFRelocSmByImport            = 0x30,                            /* Binary: 011_0000, group is "RelocSmIndex" */
  720.     kPEFRelocSmSetSectC            = 0x31,                            /* Binary: 011_0001 */
  721.     kPEFRelocSmSetSectD            = 0x32,                            /* Binary: 011_0010 */
  722.     kPEFRelocSmBySection        = 0x33,                            /* Binary: 011_0011 */
  723.     kPEFRelocIncrPosition        = 0x40,                            /* Binary: 100_0xxx */
  724.     kPEFRelocSmRepeat            = 0x48,                            /* Binary: 100_1xxx */
  725.     kPEFRelocSetPosition        = 0x50,                            /* Binary: 101_000x */
  726.     kPEFRelocLgByImport            = 0x52,                            /* Binary: 101_001x */
  727.     kPEFRelocLgRepeat            = 0x58,                            /* Binary: 101_100x */
  728.     kPEFRelocLgSetOrBySection    = 0x5A,                            /* Binary: 101_101x */
  729.     kPEFRelocUndefinedOpcode    = 0xFF                            /* Used in masking table for all undefined values. */
  730. };
  731.  
  732.  
  733.  
  734. /* ----------------------------------------------------------------------------    */
  735. /* The RelocLgSetOrBySection instruction has an additional 4 bits of subopcode.    */
  736.  
  737.  
  738. enum {
  739.     kPEFRelocLgBySectionSubopcode = 0x00,                        /* Binary: 0000 */
  740.     kPEFRelocLgSetSectCSubopcode = 0x01,                        /* Binary: 0001 */
  741.     kPEFRelocLgSetSectDSubopcode = 0x02                            /* Binary: 0010 */
  742. };
  743.  
  744. #define PEFRelocLgSetOrBySubopcode(chunk) (((chunk) >> 6) & 0x0F)
  745.  
  746.  
  747.  
  748. /* ------------------------------------------------------------------------------------------    */
  749. /* The initial values for the opcode "masking" table.  This has the enumeration values from        */
  750. /* above with appropriate replications for "don't care" bits.  It is almost certainly shorter    */
  751. /* and faster to look up the masked value in a table than to use a branch tree.                    */
  752.  
  753.  
  754. #define PEFMaskedBasicOpcodes                                                                                                                    \
  755.                                                                                                                                                 \
  756.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x00 .. 0x03 */    \
  757.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x04 .. 0x07 */    \
  758.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x08 .. 0x0B */    \
  759.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x0C .. 0x0F */    \
  760.                                                                                                                                                 \
  761.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x10 .. 0x13 */    \
  762.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x14 .. 0x17 */    \
  763.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x18 .. 0x1B */    \
  764.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x1C .. 0x1F */    \
  765.                                                                                                                                                 \
  766.             kPEFRelocBySectC,            kPEFRelocBySectD,            kPEFRelocTVector12,            kPEFRelocTVector8,            /* 0x20 .. 0x23 */    \
  767.             kPEFRelocVTable8,            kPEFRelocImportRun,            kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x24 .. 0x27 */    \
  768.                                                                                                                                                 \
  769.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x28 .. 0x2B */    \
  770.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x2C .. 0x2F */    \
  771.                                                                                                                                                 \
  772.             kPEFRelocSmByImport,        kPEFRelocSmSetSectC,        kPEFRelocSmSetSectD,        kPEFRelocSmBySection,        /* 0x30 .. 0x33 */    \
  773.                                                                                                                                                 \
  774.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x34 .. 0x37 */    \
  775.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x38 .. 0x3B */    \
  776.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x3C .. 0x3F */    \
  777.                                                                                                                                                 \
  778.             kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        /* 0x40 .. 0x43 */    \
  779.             kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        /* 0x44 .. 0x47 */    \
  780.                                                                                                                                                 \
  781.             kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            /* 0x48 .. 0x4B */    \
  782.             kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            /* 0x4C .. 0x4F */    \
  783.                                                                                                                                                 \
  784.             kPEFRelocSetPosition,        kPEFRelocSetPosition,        kPEFRelocLgByImport,        kPEFRelocLgByImport,        /* 0x50 .. 0x53 */    \
  785.                                                                                                                                                 \
  786.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x54 .. 0x57 */    \
  787.                                                                                                                                                 \
  788.             kPEFRelocLgRepeat,            kPEFRelocLgRepeat,            kPEFRelocLgSetOrBySection,    kPEFRelocLgSetOrBySection,    /* 0x58 .. 0x5B */    \
  789.                                                                                                                                                 \
  790.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x5C .. 0x5F */    \
  791.                                                                                                                                                 \
  792.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x60 .. 0x63 */    \
  793.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x64 .. 0x67 */    \
  794.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x68 .. 0x6B */    \
  795.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x6C .. 0x6F */    \
  796.                                                                                                                                                 \
  797.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x70 .. 0x73 */    \
  798.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x74 .. 0x77 */    \
  799.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x78 .. 0x7B */    \
  800.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode    /* 0x7C .. 0x7F */
  801.  
  802.  
  803.  
  804. /* =========================================================================================== */
  805. /* RelocBySectDWithSkip Instruction */
  806. /* -------------------------------- */
  807.  
  808.  
  809.  
  810. /* -------------------------------------------------------------------------------------------    */
  811. /* The "RelocBySectDWithSkip" instruction has the following bit field layout.                    */
  812. /*                                                                                                 */
  813. /*                             1         1                                                        */
  814. /*         0 1 2             9 0         5                                                        */
  815. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  816. /*        |0 0| skip count    | rel count |                                                        */
  817. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  818. /*        | 2 |<-- 8 bits --->|<--  6 --->|                                                        */
  819. /*                                                                                                 */
  820. /* ! Note that the stored skip count and reloc count are the actual values!                        */
  821.  
  822.  
  823. enum {
  824.     kPEFRelocWithSkipMaxSkipCount = 255,
  825.     kPEFRelocWithSkipMaxRelocCount = 63
  826. };
  827.  
  828. #define PEFRelocWithSkipSkipCount(chunk)    PEFRelocField ( (chunk), 2, 8 )
  829. #define PEFRelocWithSkipRelocCount(chunk)    PEFRelocField ( (chunk), 10, 6 )
  830.  
  831. #define PEFRelocComposeWithSkip(skipCount,relocCount)    \
  832.             ( 0x0000 | (((UInt16)(skipCount)) << 6) | ((UInt16)(relocCount)) )
  833.  
  834.  
  835.  
  836. /* =========================================================================================== */
  837. /* RelocRun Group */
  838. /* -------------- */
  839.  
  840.  
  841.  
  842. /* -------------------------------------------------------------------------------------------    */
  843. /* The "RelocRun" group includes the "RelocBySectC", "RelocBySectD", "RelocTVector12",            */
  844. /* "RelocTVector8", "RelocVTable8", and "RelocImportRun" instructions.  This group has the        */
  845. /* following bit field layout.                                                                    */
  846. /*                                                                                                 */
  847. /*                                       1                                                        */
  848. /*         0   2 3     6 7               5                                                        */
  849. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  850. /*        |0 1 0| subop.| run length      |                                                        */
  851. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  852. /*        |  3  |<- 4 ->|<-- 9 bits ----->|                                                        */
  853. /*                                                                                                 */
  854. /* ! Note that the stored run length is the actual value minus 1, but the macros deal with the    */
  855. /* ! actual value!                                                                                */
  856.  
  857.  
  858. enum {
  859.     kPEFRelocRunMaxRunLength    = 512
  860. };
  861.  
  862. #define PEFRelocRunSubopcode(chunk)    PEFRelocField ( (chunk), 3, 4 )
  863. #define PEFRelocRunRunLength(chunk)    (PEFRelocField ( (chunk), 7, 9 ) + 1)
  864.  
  865. #define PEFRelocComposeRun(subopcode,runLength)    \
  866.             ( 0x4000 | (((UInt16)(subopcode)) << 9) | ((UInt16)((runLength)-1)) )
  867.  
  868. #define PEFRelocComposeBySectC(runLength)        PEFRelocComposeRun ( 0, (runLength) )
  869. #define PEFRelocComposeBySectD(runLength)        PEFRelocComposeRun ( 1, (runLength) )
  870. #define PEFRelocComposeTVector12(runLength)        PEFRelocComposeRun ( 2, (runLength) )
  871. #define PEFRelocComposeTVector8(runLength)        PEFRelocComposeRun ( 3, (runLength) )
  872. #define PEFRelocComposeVTable8(runLength)        PEFRelocComposeRun ( 4, (runLength) )
  873. #define PEFRelocComposeImportRun(runLength)        PEFRelocComposeRun ( 5, (runLength) )
  874.  
  875.  
  876.  
  877. /* =========================================================================================== */
  878. /* RelocSmIndex Group */
  879. /* ------------------ */
  880.  
  881.  
  882.  
  883. /* ----------------------------------------------------------------------------------------    */
  884. /* The "RelocSmIndex" group includes the "RelocSmByImport", "RelocSmSetSectC",                */
  885. /* "RelocSmSetSectD" and "RelocSmBySection" instructions.  This group has the following bit    */
  886. /* field layout.                                                                            */
  887. /*                                                                                             */
  888. /*                                       1                                                    */
  889. /*         0   2 3     6 7               5                                                    */
  890. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    */
  891. /*        |0 1 1| subop.| index           |                                                    */
  892. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    */
  893. /*        |  3  |<- 4 ->|<-- 9 bits ----->|                                                    */
  894. /*                                                                                             */
  895. /* ! Note that the stored index is the actual value!                                        */
  896.  
  897.  
  898. enum {
  899.     kPEFRelocSmIndexMaxIndex    = 511
  900. };
  901.  
  902. #define PEFRelocSmIndexSubopcode(chunk)    PEFRelocField ( (chunk), 3, 4 )
  903. #define PEFRelocSmIndexIndex(chunk)        PEFRelocField ( (chunk), 7, 9 )
  904.  
  905. #define PEFRelocComposeSmIndex(subopcode,index)    \
  906.             ( 0x6000 | (((UInt16)(subopcode)) << 9) | ((UInt16)(index)) )
  907.  
  908. #define PEFRelocComposeSmByImport(index)    PEFRelocComposeSmIndex ( 0, (index) )
  909. #define PEFRelocComposeSmSetSectC(index)    PEFRelocComposeSmIndex ( 1, (index) )
  910. #define PEFRelocComposeSmSetSectD(index)    PEFRelocComposeSmIndex ( 2, (index) )
  911. #define PEFRelocComposeSmBySection(index)    PEFRelocComposeSmIndex ( 3, (index) )
  912.  
  913.  
  914.  
  915. /* =========================================================================================== */
  916. /* RelocIncrPosition Instruction */
  917. /* ----------------------------- */
  918.  
  919.  
  920.  
  921. /* -------------------------------------------------------------------------------------------    */
  922. /* The "RelocIncrPosition" instruction has the following bit field layout.                        */
  923. /*                                                                                                 */
  924. /*                                       1                                                        */
  925. /*         0     3 4                     5                                                        */
  926. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  927. /*        |1 0 0 0| offset                |                                                        */
  928. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  929. /*        |<- 4 ->|<-- 12 bits ---------->|                                                        */
  930. /*                                                                                                 */
  931. /* ! Note that the stored offset is the actual value minus 1, but the macros deal with the        */
  932. /* ! actual value!                                                                                */
  933.  
  934.  
  935. enum {
  936.     kPEFRelocIncrPositionMaxOffset = 4096
  937. };
  938.  
  939. #define PEFRelocIncrPositionOffset(chunk)    (PEFRelocField ( (chunk), 4, 12 ) + 1)
  940.  
  941. #define PEFRelocComposeIncrPosition(offset)    \
  942.             ( 0x8000 | ((UInt16)((offset)-1)) )
  943.  
  944.  
  945.  
  946. /* =========================================================================================== */
  947. /* RelocSmRepeat Instruction */
  948. /* ------------------------- */
  949.  
  950.  
  951.  
  952. /* -------------------------------------------------------------------------------------------    */
  953. /* The "RelocSmRepeat" instruction has the following bit field layout.                            */
  954. /*                                                                                                 */
  955. /*                                       1                                                        */
  956. /*         0     3 4     7 8             5                                                        */
  957. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  958. /*        |1 0 0 1| chnks | repeat count  |                                                        */
  959. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  960. /*        |<- 4 ->|<- 4 ->|<-- 8 bits --->|                                                        */
  961. /*                                                                                                 */
  962. /* ! Note that the stored chunk count and repeat count are the actual values minus 1, but the    */
  963. /* ! macros deal with the actual values!                                                        */
  964.  
  965.  
  966. enum {
  967.     kPEFRelocSmRepeatMaxChunkCount = 16,
  968.     kPEFRelocSmRepeatMaxRepeatCount = 256
  969. };
  970.  
  971. #define PEFRelocSmRepeatChunkCount(chunk)    (PEFRelocField ( (chunk), 4, 4 ) + 1)
  972. #define PEFRelocSmRepeatRepeatCount(chunk)    (PEFRelocField ( (chunk), 8, 8 ) + 1)
  973.  
  974. #define PEFRelocComposeSmRepeat(chunkCount,repeatCount)    \
  975.             ( 0x9000 | ((((UInt16)(chunkCount))-1) << 8) | (((UInt16)(repeatCount))-1) )
  976.  
  977.  
  978.  
  979. /* =========================================================================================== */
  980. /* RelocSetPosition Instruction */
  981. /* ---------------------------- */
  982.  
  983.  
  984.  
  985. /* -------------------------------------------------------------------------------------------    */
  986. /* The "RelocSetPosition" instruction has the following bit field layout.                        */
  987. /*                                                                                                 */
  988. /*                                       1                                   1                    */
  989. /*         0         5 6                 5     0                             5                    */
  990. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  991. /*        |1 0 1 0 0 0| offset (high)     |   | offset (low)                  |                    */
  992. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  993. /*        |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    */
  994. /*                                                                                                 */
  995. /* ! Note that the stored offset is the actual value!                                            */
  996.  
  997.  
  998. enum {
  999.     kPEFRelocSetPosMaxOffset    = 0x03FFFFFF                    /* 67,108,863 */
  1000. };
  1001.  
  1002. #define PEFRelocSetPosOffsetHigh(chunk)    PEFRelocField ( (chunk), 6, 10 )
  1003.  
  1004. #define PEFRelocSetPosFullOffset(firstChunk,secondChunk)    \
  1005.             ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) )
  1006.  
  1007. #define PEFRelocComposeSetPosition(fullOffset)    \
  1008.             ( 0xA000 | ((UInt16) (((UInt32)(fullOffset)) >> 16) ) )
  1009.  
  1010.  
  1011.  
  1012. /* =========================================================================================== */
  1013. /* RelocLgByImport Instruction */
  1014. /* --------------------------- */
  1015.  
  1016.  
  1017.  
  1018. /* -------------------------------------------------------------------------------------------    */
  1019. /* The "RelocLgByImport" instruction has the following bit field layout.                        */
  1020. /*                                                                                                 */
  1021. /*                                       1                                   1                    */
  1022. /*         0         5 6                 5     0                             5                    */
  1023. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1024. /*        |1 0 1 0 0 1| index (high)      |   | index (low)                   |                    */
  1025. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1026. /*        |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    */
  1027. /*                                                                                                 */
  1028. /* ! Note that the stored offset is the actual value!                                            */
  1029.  
  1030.  
  1031. enum {
  1032.     kPEFRelocLgByImportMaxIndex    = 0x03FFFFFF                    /* 67,108,863 */
  1033. };
  1034.  
  1035. #define PEFRelocLgByImportIndexHigh(chunk)    PEFRelocField ( (chunk), 6, 10 )
  1036.  
  1037. #define PEFRelocLgByImportFullIndex(firstChunk,secondChunk)    \
  1038.             ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) )
  1039.  
  1040. #define PEFRelocComposeLgByImport(fullIndex)    \
  1041.             ( 0xA400 | ((UInt16) (((UInt32)(fullIndex)) >> 16) ) )
  1042.  
  1043.  
  1044.  
  1045. /* =========================================================================================== */
  1046. /* RelocLgRepeat Instruction */
  1047. /* ------------------------- */
  1048.  
  1049.  
  1050.  
  1051. /* -------------------------------------------------------------------------------------------    */
  1052. /* The "RelocLgRepeat" instruction has the following bit field layout.                            */
  1053. /*                                                                                                 */
  1054. /*                             1         1                                   1                    */
  1055. /*         0         5 6     9 0         5     0                             5                    */
  1056. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1057. /*        |1 0 1 1 0 0| chnks | rpt (high)|   | repeat count (low)            |                    */
  1058. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1059. /*        |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    */
  1060. /*                                                                                                 */
  1061. /* ! Note that the stored chunk count is the actual value minus 1, but the macros deal with        */
  1062. /* ! the actual value!  The stored repeat count is the actual value!                            */
  1063.  
  1064.  
  1065. enum {
  1066.     kPEFRelocLgRepeatMaxChunkCount = 16,
  1067.     kPEFRelocLgRepeatMaxRepeatCount = 0x003FFFFF                /* 4,194,303 */
  1068. };
  1069.  
  1070. #define PEFRelocLgRepeatChunkCount(chunk)        (PEFRelocField ( (chunk), 6, 4 ) + 1)
  1071. #define PEFRelocLgRepeatRepeatCountHigh(chunk)    PEFRelocField ( (chunk), 10, 6 )
  1072.  
  1073. #define PEFRelocLgRepeatFullRepeatCount(firstChunk,secondChunk)    \
  1074.             ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) )
  1075.  
  1076. #define PEFRelocComposeLgRepeat(chunkCount,fullRepeatCount)    \
  1077.             ( 0xB000 | ((((UInt16)(chunkCount))-1) << 6) | ((UInt16) (((UInt32)(fullRepeatCount)) >>16 ) ) )
  1078.  
  1079.  
  1080.  
  1081. /* =========================================================================================== */
  1082. /* RelocLgSetOrBySection Group */
  1083. /* --------------------------- */
  1084.  
  1085.  
  1086.  
  1087. /* -------------------------------------------------------------------------------------------    */
  1088. /* The "RelocLgSetOrBySection" instruction is really a group including the "RelocLgBySection",    */
  1089. /* "RelocLgSetSectC" and "RelocLgSetSectD" instructions.  This group has the following bit        */
  1090. /* field layout.                                                                                */
  1091. /*                                                                                                 */
  1092. /*                             1         1                                   1                    */
  1093. /*         0         5 6     9 0         5     0                             5                    */
  1094. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1095. /*        |1 0 1 1 0 1| subop | idx (high)|   | index (low)                   |                    */
  1096. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1097. /*        |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    */
  1098. /*                                                                                                 */
  1099. /* ! Note that the stored index is the actual value!                                            */
  1100.  
  1101.  
  1102. enum {
  1103.     kPEFRelocLgSetOrBySectionMaxIndex = 0x003FFFFF                /* 4,194,303 */
  1104. };
  1105.  
  1106. #define PEFRelocLgSetOrBySectionSubopcode(chunk)    PEFRelocField ( (chunk), 6, 4 )
  1107. #define PEFRelocLgSetOrBySectionIndexHigh(chunk)    PEFRelocField ( (chunk), 10, 6 )
  1108.  
  1109. #define PEFRelocLgSetOrBySectionFullIndex(firstChunk,secondChunk)    \
  1110.             ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) )
  1111.  
  1112. #define PEFRelocComposeLgSetOrBySection(subopcode,fullIndex)    \
  1113.             ( 0xB400 | (((UInt16)(subopcode)) << 6) | ((UInt16) (((UInt32)(fullCount)) >> 16) ) )
  1114.  
  1115. #define PEFRelocComposeLgBySection(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x00, (fullIndex) )
  1116. #define PEFRelocComposeLgSetSectC(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x01, (fullIndex) )
  1117. #define PEFRelocComposeLgSetSectD(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x02, (fullIndex) )
  1118.  
  1119.  
  1120.  
  1121. #if PRAGMA_STRUCT_ALIGN
  1122.     #pragma options align=reset
  1123. #elif PRAGMA_STRUCT_PACKPUSH
  1124.     #pragma pack(pop)
  1125. #elif PRAGMA_STRUCT_PACK
  1126.     #pragma pack()
  1127. #endif
  1128.  
  1129. #ifdef PRAGMA_IMPORT_OFF
  1130. #pragma import off
  1131. #elif PRAGMA_IMPORT
  1132. #pragma import reset
  1133. #endif
  1134.  
  1135. #ifdef __cplusplus
  1136. }
  1137. #endif
  1138.  
  1139. #endif /* __PEFBINARYFORMAT__ */
  1140.  
  1141.